home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 June
/
Macworld (1999-06).dmg
/
Shareware World
/
Info
/
For Developers
/
MacZoop2.0.sea
/
MacZoop2.0
/
Required Classes
/
ZObject.h
< prev
next >
Wrap
Text File
|
1999-02-24
|
4KB
|
136 lines
/*************************************************************************************************
*
*
* MacZoop - "the framework for the rest of us"
*
*
*
* ZObject.h -- the root object (abstract class)
*
*
*
*
*
* © 1998, Graham Cox
*
*
*
*
*************************************************************************************************/
#pragma once
#ifndef __ZOBJECT__
#define __ZOBJECT__
class ZObject;
class ZStream;
class ZClassRegistry;
typedef ZObject* (*ConstructorFunction)();
/*
In order to permit MacZoop to implement object streaming (persistent objects), all objects
need to have a common root. This is it- ZObject. Most classes ultimately derive from this and
are thus streamable.
ZObject relies on ZClassRegistry to store a table of class ID's, names and intantiation
functions. Every class you wish to create from a stream must be registered with <gClasses> in
order to work- this is normally done at app startup time when ZApplication's RegisterClasses()
method is called. The standard method only registers the required classes.
Class ID's are four-char codes. MacZoop reserves all lower-case only codes for itself- for
classes of your own, use one or more upper case letters and make sure it's unique. The classID
must be assigned in your constructor.
In addition, all streamable classes must have a default constructor- i.e. one that has no
parameters. You must also write a CONSTRUCTION FUNCTION, which just makes an object of the
declared type using the default constructor. This goes like this:
ZObject* MyConstructorFunction()
{
return new MyClass();
}
The function is passed to ZClassRegistry's RegisterClass() method, along with the classID and
class name.
The following macros are provided to make all this setup much easier. They expand to the proper
class ID and constructor function defeinitions so you can simply deploy them in your classes and
forget about 'em.
*/
// This handy macro saves you having to do much work to create you class constructor functions. All
// you have to do is put this at the top of your .cpp file where you want a constructor function,
// passing the class name. This will be expanded into a constructor function of the correct type.
// i.e. CLASSCONSTRUCTOR( ZWindow ); -> ZObject* CF_ZWindow() { return new ZWindow(); };
#define CLASSCONSTRUCTOR( x ) ZObject* CF_##x##() { return new x(); }
// to place a prototype for the constructor function, use this. NOte that normally this is unnecessary
// since the DEFINECLASSID will also do this for you in the appropriate place.
#define CLASSCFPROTOTYPE( x ) ZObject* CF_##x##()
// to establish the proper class ID identifier for your class, put this in your class header:
// x is the class identifier, e.g. ZWindow, id is the desired ID, e.g. 'zwin'.
#define DEFINECLASSID( x, id ) enum { CLASS_##x = id }; CLASSCFPROTOTYPE( x )
// to determine the name of the constructor function from your class identifier, use:
#define CONSTRUCTORFUNCTION( x ) CF_##x
// to make a readable pascal style class name for your class:
#define CLASSNAME( x ) CLITERAL( \p##x )
// handy way to get your class ID from your class name
#define CLASSID( x ) CLASS_##x
// So when registering a class, you need only do:
// gClasses->RegisterClass( CLASSID( ZWindow ), CONSTRUCTORFUNCTION( ZWindow ), CLASSNAME( ZWindow ));
// even better, ZClassRegistry has a macro that expands to this from a single class identifier:
// e.g. REGISTERCLASS( ZWindow );
DEFINECLASSID( ZObject, 'zobj' );
// class definition:
class ZObject
{
protected:
OSType classID; // class ID of object- subclasses must set this
long instanceID; // instance ID- not yet used. Reserved.
public:
ZObject() { classID = CLASS_ZObject; instanceID = 0; };
virtual ~ZObject(){};
// info:
void GetClassName( Str255 aName );
long GetClassRef() { return classID; };
long GetInstanceID() { return instanceID; };
void SetClassID( OSType id ) { classID = id; };
// streaming:
virtual void ReadFromStream( ZStream* aStream ) {};
virtual void WriteToStream( ZStream* aStream ) {};
};
extern ZClassRegistry* gClasses;
#endif